using System.Text.RegularExpressions;
using MongoDB.Driver;
using TangMonk.Component;
using TangMonk.Models;

namespace TangMonk.Service;

public class LoginContext
{
    private readonly Dictionary<UserLoginType, LoginStrategy> _strategies;

    public LoginContext(IMongoCollection<User> userCollection)
    {
        _strategies = new Dictionary<UserLoginType, LoginStrategy>
        {
            { UserLoginType.UserName, new UserNameLogin(userCollection) },
            { UserLoginType.Email, new EmailLogin(userCollection) },
            { UserLoginType.IdCard, new IdCardLogin(userCollection) },
            { UserLoginType.Phone, new PhoneLogin(userCollection) }
        };
    }

    public RequestUserResult Login(UserLoginType type, string credential, string password)
    {
        if (!_strategies.ContainsKey(type))
            return new RequestUserResult(new List<User>(), new RequestResult
            {
                Action = "user login",
                Result = "unknown login type",
                Success = false
            }); // 未知登录类型
        _strategies[type].CanHandle(credential);
        var result = _strategies[type].Verify(credential, password);

        return result;
    }
}

public partial class UserNameLogin : LoginStrategy
{
    public UserNameLogin(IMongoCollection<User> userCollection) : base(userCollection)
    {
    }

    public override bool CanHandle(string identifier)
    {
        return MyRegex().IsMatch(identifier); // 假设手机号为11位数字
    }

    public override RequestUserResult Verify(string identifier, string password)
    {
        var user = UserCollection.Find(x => x.Phone == identifier).FirstOrDefault();
        var canLogin = user.Password == password;
        var userGroup = new List<User> { user };
        var result = new RequestUserResult(userGroup, new RequestResult("user login", canLogin));
        return result;
    }

    [GeneratedRegex("^\\d{11}$")]
    private static partial Regex MyRegex();
}

public partial class EmailLogin : LoginStrategy
{
    public EmailLogin(IMongoCollection<User> userCollection) : base(userCollection)
    {
    }

    public override bool CanHandle(string identifier)
    {
        return MyRegex().IsMatch(identifier); // 简单的邮箱格式验证
    }

    public override RequestUserResult Verify(string identifier, string password)
    {
        var user = UserCollection.Find(x => x.Email == identifier).First();
        var canLogin = user.Password == password;
        var userGroup = new List<User> { user };
        var result = new RequestUserResult(userGroup, new RequestResult("user login", canLogin));
        return result;
    }

    [GeneratedRegex(@"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$")]
    private static partial Regex MyRegex();
}

public partial class IdCardLogin : LoginStrategy
{
    public IdCardLogin(IMongoCollection<User> userCollection) : base(userCollection)
    {
    }

    public override bool CanHandle(string identifier)
    {
        return MyRegex().IsMatch(identifier);
    }

    public override RequestUserResult Verify(string identifier, string password)
    {
        var user = UserCollection.Find(x => x.IdentityCard == identifier).First();
        var canLogin = user.Password == password;
        var userGroup = new List<User> { user };
        var result = new RequestUserResult(userGroup, new RequestResult("user login", canLogin));
        return result;
    }

    [GeneratedRegex(@"^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|X|x)$")]
    private static partial Regex MyRegex();
}

public partial class PhoneLogin : LoginStrategy
{
    public PhoneLogin(IMongoCollection<User> userCollection) : base(userCollection)
    {
    }

    public override bool CanHandle(string identifier)
    {
        return MyRegex().IsMatch(identifier);
    }

    public override RequestUserResult Verify(string identifier, string password)
    {
        var user = UserCollection.Find(x => x.Phone == identifier).First();
        var canLogin = user.Password == password;
        var userGroup = new List<User> { user };
        var result = new RequestUserResult(userGroup, new RequestResult("user login", canLogin));
        return result;
    }

    [GeneratedRegex(@"^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$")]
    private static partial Regex MyRegex();
}